module namespace impl = "urn:X-FGeorges:xslt:google:data:impl";

declare namespace xsl = "http://www.w3.org/1999/XSL/Transform";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare namespace doc = "http://www.CraneSoftwrights.com/ns/xslstyle";
declare namespace gdata = "http://fgeorges.org/ns/google/data";
declare namespace atom = "http://www.w3.org/2005/Atom";
declare namespace os = "http://a9.com/-/spec/opensearch/1.1/";
declare namespace http = "http://expath.org/ns/http-client";
declare namespace x2x = "TODO-xslt-to-xquery";

import module "http://expath.org/ns/http-client";
import module "http://fgeorges.org/ns/google/data";
declare variable $impl:app-name as xs:string := ( 'fgeorges-xsl-gdata-0.1' );
declare variable $impl:auth-endpoint as xs:string := (         'https://www.google.com/accounts/ClientLogin' );
declare function impl:get-stuff($service as element(gdata:service), $stuff-uri as xs:string, $params as element(gdata:param)*, $since as item()?) as element()?
{
 (),  (), let $uri as xs:string := (            gdata:encode-params($stuff-uri, $params) )
   return (
       (),  (), let $req as element(http:request) := (  (), element http:request { attribute method { 'get' } , attribute href { '{ $uri }' } ,  (), element http:header { attribute name { 'GData-Version' } , attribute value { '2' }  } ,  (), element http:header { attribute name { 'Authorization' } , attribute value { 'GoogleLogin auth={ $service/gdata:auth-token }' }  } ,  (), impl:make-since-header($since),  () } ,  () )
   return (
       (),  (), let $resp := ( http:send-request($req) )
   return (
       (),  (),  if ( not(count($resp) = (1, 2)) ) then (  (), gdata:error('HTTPCL004'),  () ) else () ,  (),  if ( exists($resp[2]) and not($resp[2] instance of document-node()) ) then (  (), gdata:error('HTTPCL005', $resp[1]/http:body/@content-type),  () ) else () ,  (),  if ( xs:integer($resp[1]/@status) ne 200 ) then (  (), gdata:error('HTTPCL006', $resp[1]/@status, $resp[1]/@message),  () ) else () ,  (), $resp[2]/*,  ()   )
   )
   )
};
declare function impl:make-since-header($since as item()?) as element(http:header)*
{
 (),  if ( empty($since) ) then (  (),  () )
 else if ( $since instance of xs:dateTime ) then (  (), element http:header { attribute name { 'If-Modified-Since' } , attribute value { '{ impl:format-datetime-rfc1123($since) }' }  } ,  () )
 else if ( $since instance of xs:date ) then (  (), element http:header { attribute name { 'If-Modified-Since' } , attribute value { '{ impl:format-date-rfc1123($since) }' }  } ,  () )
 else if ( $since instance of xs:string ) then (  (), element http:header { attribute name { 'If-None-Match' } , attribute value { '{ $since }' }  } ,  () )
 else (  (), gdata:error('HTTPCL008'),  () )
,  ()};
declare function impl:get-all-feeds($service as element(gdata:service), $feed-uri as xs:string, $start as xs:integer, $max as xs:integer, $params as element(gdata:param)*) as element(atom:feed)+
{
 (),  (), let $start-param as element(gdata:param) := (  (), element gdata:param { attribute name { 'start-index' } , attribute value { '{ $start }' }  } ,  () )
   return (
       (),  (), let $this := (            gdata:get-feed($service, $feed-uri, ($params, $start-param)) )
   return (
       (),  (), let $last := (            xs:integer($this/os:startIndex) + count($this/atom:entry) - 1 )
   return (
       (),  (), $this,  (),  (),  if ( $last lt xs:integer($this/os:totalResults) ) then (  (),               impl:get-all-feeds($service, $feed-uri, $start + $max, $max, $params),  () ) else () ,  ()   )
   )
   )
};
declare function impl:format-date-rfc1123($date as xs:date) as xs:string
{
 (), let $month-abbrevs as xs:string+ := (            'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' )
   return (
       (),  (), concat(           day-from-date($date),           ' ',           $month-abbrevs[month-from-date($date)],           ' ',           year-from-date($date),           ' 00:00:00 ',           impl:format-zone(timezone-from-date($date))         ),  ()   )
};
declare function impl:format-datetime-rfc1123($dt as xs:dateTime) as xs:string
{
 (), let $month-abbrevs as xs:string+ := (            'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' )
   return (
       (),  (), concat(           day-from-dateTime($dt),           ' ',           $month-abbrevs[month-from-dateTime($dt)],           ' ',           year-from-dateTime($dt),           ' ',           if ( hours-from-dateTime($dt) lt 10 ) then '0' else (),           hours-from-dateTime($dt),           ':',           if ( minutes-from-dateTime($dt) lt 10 ) then '0' else (),           minutes-from-dateTime($dt),           ':',           if ( seconds-from-dateTime($dt) lt 10 ) then '0' else (),           seconds-from-dateTime($dt),           ' ',           impl:format-zone(timezone-from-dateTime($dt))         ),  ()   )
};
declare function impl:format-zone($zone as xs:dayTimeDuration?) as xs:string
{
 (), let $hour := ( hours-from-duration($zone) )
   return (
       (), let $min := ( minutes-from-duration($zone) )
   return (
       (),  if ( empty($zone) or ($hour eq 0 and $min eq 0) ) then (  (), 'Z',  () )
 else (  (),                  concat(if ( $hour lt 0 ) then '-' else '+',                        if ( $hour lt 10 and $hour gt -10 ) then '0' else '',                        string(abs($hour)),                        if ( $min lt 10 and $min gt -10 ) then '0' else '',                        string(abs($min))),  () )
,  ()   )
   )
};
